package com.black.cat.jvm.classfile;

import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.util.Arrays;

/**
 * @Author blackcat
 * @create 2021/8/12 8:20
 * @version: 1.0
 * @description:读取class数据
 *
 *  java虚拟机定义了u1、u2、u4三种数据类型来表示；1字节、2字节、4字节，无符号整数。
 */
public class ClassReader {


    private byte[] codes;
    private int pos;

    public ClassReader(byte[] codes) {
        this.codes = codes;
        this.pos = 0;
    }

    //u1
    public int nextU1toInt() {
        return ByteUtil.byteToInt(new byte[] { codes[pos++] });
    }

    //u2
    public int nextU2ToInt() {
        return ByteUtil.byteToInt(new byte[] { codes[pos++], codes[pos++] });
    }

    //u4
    public int nextU4ToInt() {
        return ByteUtil.byteToInt(new byte[] { codes[pos++], codes[pos++], codes[pos++], codes[pos++] });
    }

    //u4 转String
    public String nextU4ToHexString() {
        return ByteUtil.byteToHexString((new byte[] { codes[pos++], codes[pos++], codes[pos++], codes[pos++] }));
    }

    public long next2U4ToLong() {
        byte[] bytes = nextBytes(8);
        return ByteBuffer.wrap(bytes).order(ByteOrder.BIG_ENDIAN).getLong();
    }

    public double next2U4Double() {
        byte[] bytes = nextBytes(8);
        return ByteBuffer.wrap(bytes).order(ByteOrder.BIG_ENDIAN).getDouble();
    }

    public float nextU4ToFloat() {
        byte[] bytes = nextBytes(4);
        return ByteBuffer.wrap(bytes).order(ByteOrder.BIG_ENDIAN).getFloat();
    }


    public int[] nextUint16s() {
        int count = nextU2ToInt();
        int[] result = new int[count];
        for (int i = 0; i < count; i++) {
            result[i] = nextU2ToInt();
        }
        return result;
    }

    //读取长度为len的数据
    public byte[] nextBytes(int len) {
        if (pos + len >= codes.length) {
            throw new ArrayIndexOutOfBoundsException();
        }

        byte[] data = Arrays.copyOfRange(codes, pos, pos + len);
        pos += len;
        return data;
    }
}
